package cn.yunyichina.provider.pay.main;

import cn.yunyichina.provider.framework.annotation.validate.ValidateException;
import cn.yunyichina.provider.framework.common.ResponseEnum;
import cn.yunyichina.provider.framework.data.SpringContextHandler;
import cn.yunyichina.provider.framework.dubbo.service.impl.YytServiceImpl;
import cn.yunyichina.provider.framework.exception.CallException;
import cn.yunyichina.provider.framework.utils.UUIDUtil;
import cn.yunyichina.provider.iface.entity.alipay.AddCouponRequest;
import cn.yunyichina.provider.iface.entity.alipay.AddCouponResponse;
import cn.yunyichina.provider.iface.entity.common.ResCommon;
import cn.yunyichina.provider.iface.entity.pay.*;
import cn.yunyichina.provider.iface.service.IPay;
import cn.yunyichina.provider.pay.constant.QueryJouralResponse;
import cn.yunyichina.provider.pay.dao.PaymentJournalDao;
import cn.yunyichina.provider.pay.dao.PaymentSettingAppRelationDao;
import cn.yunyichina.provider.pay.dao.PaymentSettingDao;
import cn.yunyichina.provider.pay.dao.TradeRecordDao;
import cn.yunyichina.provider.pay.entity.PaymentJournal;
import cn.yunyichina.provider.pay.entity.PaymentSetting;
import cn.yunyichina.provider.pay.entity.PaymentSettingAppRelation;
import cn.yunyichina.provider.pay.service.CouponService;
import cn.yunyichina.provider.pay.service.impl.PaymentJournalServiceImpl;
import cn.yunyichina.provider.pay.service.impl.PaymentSettingServiceImpl;
import cn.yunyichina.provider.pay.utils.BeanValidator;
import cn.yunyichina.utils.commons.DateUtils;
import cn.yunyichina.utils.convert.JsonUtils;
import cn.yunyichina.utils.dozer.Dozer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static cn.yunyichina.utils.commons.DateUtils.StringToDate;

/**
 * 支付中心服务子系统dubbo入口
 *
 * @author zhangkw
 * @date 2016-07-29
 */
public class PayServiceImpl extends YytServiceImpl implements IPay {

    public String getErrorCode() {
        return "5000";
    }

    private static final Logger logger = LoggerFactory.getLogger(PayServiceImpl.class);

    @Autowired
    private PaymentSettingAppRelationDao appRelationDao;

    @Autowired
    private PaymentSettingDao settingDao;

    @Autowired
    private TradeRecordDao tradeRecordDao;

    @Autowired
    private CouponService couponService;

    @Autowired
    private PaymentJournalServiceImpl paymentJournalServiceImpl;

    @Autowired
    private PaymentJournalDao paymentJournalDao;

    public ResCommon<PaymentSettingAppRelationResponse> getPaymentId(PaymentSettingAppRelationVo paymentSettingVo) {
        ResCommon<PaymentSettingAppRelationResponse> res = new ResCommon<>();

        PaymentSettingAppRelation appRelation = new PaymentSettingAppRelation();
        appRelation.setPlatformOrgAppCode(paymentSettingVo.getOrgAppCode());
        appRelation.setPayMode(paymentSettingVo.getPayMode());
        List<PaymentSettingAppRelation> lists = appRelationDao.select(appRelation);

        if (lists != null && lists.size() > 0) {
            PaymentSettingAppRelationResponse response = new PaymentSettingAppRelationResponse();
            PaymentSettingAppRelation appRelationTmp = lists.get(0);
            response.setPaymentId(appRelationTmp.getPaymentSettingId());
            res.setResult(response);
        }

        return res;
    }

    public ResCommon<PaymentSettingResponse> getPayKey(PaymentSettingVo paymentSettingVo) {
        ResCommon<PaymentSettingResponse> res = new ResCommon<>();

        PaymentSetting setting = settingDao.selectById(paymentSettingVo.getId());
        if (setting != null) {
            PaymentSettingResponse response = new PaymentSettingResponse();
            response.setPayKey(setting.getSecretKey());
            res.setResult(response);
        }

        return res;
    }

    public ResCommon<PaymentSettingResponse> queryPaymentSettingByAppcodeAndOrgcodeAndPaymode(
            String platformOrgAppCode, String orgCode, short payMode) {
        ResCommon<PaymentSettingResponse> res = new ResCommon<>();

        try {
            PaymentSettingServiceImpl service = SpringContextHandler.getBean("paymentSettingServiceImpl");
            PaymentSetting paymentSetting = service.queryPaymentSettingByAppcodeAndOrgcodeAndPaymode(platformOrgAppCode, orgCode, payMode);
            if (paymentSetting == null) {
                res.setResultCodeAndMessage("5000", "queryPaymentSettingByAppcodeAndOrgcodeAndPaymode查询结果为空！");
            } else {
                res.setResultCodeAndMessage("0", "查询成功!");
                PaymentSettingResponse psResponse = new PaymentSettingResponse();
                BeanUtils.copyProperties(paymentSetting, psResponse);
                res.setResult(psResponse);
            }
        } catch (CallException cex) {
            res.setResultCodeAndMessage(cex.getResultCode(), cex.getMessage());
        } catch (Exception ex) {
            logger.error("queryPaymentSettingByAppcodeAndOrgcodeAndPaymode异常", ex);
            res.setResultCodeAndMessage("5000", "queryPaymentSettingByAppcodeAndOrgcodeAndPaymode异常:" + ex.getMessage());
        }

        return res;
    }

    public ResCommon<PaymentSettingResponse> queryPaymentSettingByAppId(String appId) {
        ResCommon<PaymentSettingResponse> res = new ResCommon<>();

        PaymentSetting query = new PaymentSetting();
        query.setPayAppId(appId);

        List<PaymentSetting> settingList = settingDao.select(query);

        PaymentSettingResponse paymentSettingResponse = new PaymentSettingResponse();
        BeanUtils.copyProperties(settingList.get(0), paymentSettingResponse);

        res.setResult(paymentSettingResponse);
        return res;
    }

    public ResCommon<List<TradeRecordResponse>> queryTradeRecord(TradeRecordRequest tradeRecordRequest) {
        logger.info("TradeRecordServiceImpl.queryTradeRecord.tradeRecordRequest -> {}", JsonUtils.toJsonString(tradeRecordRequest));

        ResCommon<List<TradeRecordResponse>> resCommon = new ResCommon<>();

        if (checkQueryTradeRecordParameters(tradeRecordRequest)) {
            List<TradeRecordResponse> recordDaoList = tradeRecordDao.queryTradeRecord(tradeRecordRequest);

            if (!CollectionUtils.isEmpty(recordDaoList)) {
                resCommon.setResult(recordDaoList);
            }
        } else {
            resCommon.setResultCodeAndMessage(
                    ResponseEnum.Common.INVALID.getCode(),
                    ResponseEnum.Common.INVALID.getMessage()
            );
        }

        return resCommon;
    }

    public AddCouponResponse addCouponInstance(AddCouponRequest request) {
        return couponService.addCouponInstance(request);
    }

    private boolean checkQueryTradeRecordParameters(TradeRecordRequest request) {
        if (StringUtils.isEmpty(request.getAppid()) ||
                StringUtils.isEmpty(request.getOrderType()) ||
                StringUtils.isEmpty(request.getTradeType()) ||
                StringUtils.isEmpty(request.getStartTime()) ||
                StringUtils.isEmpty(request.getEndTime())) {
            return false;
        }

        return true;
    }

    @Override
    public ResCommon<PaymentSettingResponse> getPaymentSettingById(String paymentSettingId) {
        logger.debug("getPaymentSettingById:" + paymentSettingId);
        if (StringUtils.isEmpty(paymentSettingId)) {
            logger.error("请输入paymentSettingId");
            throw new CallException("-1", "请输入paymentSettingId");
        }
        ResCommon<PaymentSettingResponse> res = new ResCommon<PaymentSettingResponse>();
        PaymentSetting setting = settingDao.selectById(paymentSettingId);
        PaymentSettingResponse response = JsonUtils.parseObject(setting, PaymentSettingResponse.class);
        res.setResult(response);
        logger.debug("getPaymentSettingById结果:" + JsonUtils.toJsonString(res));
        return res;
    }

    @Override
    public void updatePaymentJournalRefundFlagByOrderNo(String orderNo, short isRefundFlag) {
        paymentJournalServiceImpl.updatePaymentJournalRefundFlagByOrderNo(orderNo, isRefundFlag);
    }

    @Override
    public ResCommon addPaymentJournal(PaymentJournalVo paymentJournalVo) {
        ResCommon response = new ResCommon();

        try {
            PaymentJournal paymentJournal = Dozer.convert(paymentJournalVo, PaymentJournal.class);
            if (StringUtils.isEmpty(paymentJournal.getId())) {
                paymentJournal.setId(UUIDUtil.get32UUID());
            }

            paymentJournalDao.insert(paymentJournal);
        } catch (Exception e) {
            logger.error("PayServiceImpl.addPaymentJournal.Exception", e);
            response.setResultCodeAndMessage(
                    ResponseEnum.Common.FAILURE.getCode(),
                    ResponseEnum.Common.FAILURE.getMessage()
            );
        }

        return response;
    }

    @Override
    public ResCommon<List<PaymentJournalResponseOut>> paymentJournalQuery(PaymentJournalVoOut paymentJournalVoOut) {
        logger.info("PayServiceImpl.PaymentJournalQuery.paymentJournalVoOut -> {}", JsonUtils.toJsonString(paymentJournalVoOut));
        ResCommon<List<PaymentJournalResponseOut>> resCommon = new ResCommon<>();
        if (StringUtils.isEmpty(paymentJournalVoOut)) {
            logger.error("paymentJournalVoOut为空或null");
            throw new CallException("-1", "paymentJournalVoOut为空或null");
        }
        try {
            BeanValidator.validate(paymentJournalVoOut);
            if (StringToDate(paymentJournalVoOut.getStartTime()).getTime()
                    > StringToDate((paymentJournalVoOut.getEndTime())).getTime()) {
                logger.info("订单开始时间:【{}】大于结束时间【{}】", paymentJournalVoOut.getStartTime(), paymentJournalVoOut.getEndTime());
                resCommon.setResultCodeAndMessage(QueryJouralResponse.Common.TIME_ERR.getCode(), QueryJouralResponse.Common.TIME_ERR.getMessage());
            } else if (StringToDate(DateUtils.getStringDayAfter(paymentJournalVoOut.getStartTime(), 7)).getTime()
                    - StringToDate(paymentJournalVoOut.getEndTime()).getTime() < 0) {
                logger.info("订单开始时间:【{}】与结束时间【{}】间隔不能超过7天", paymentJournalVoOut.getStartTime(), paymentJournalVoOut.getEndTime());
                resCommon.setResultCodeAndMessage(QueryJouralResponse.Common.TIME_EXCEESS.getCode(),
                        QueryJouralResponse.Common.TIME_EXCEESS.getMessage());
            } else {
                Short orderModer = paymentJournalVoOut.getOrderMode();
                Short tradeModer = paymentJournalVoOut.getTradeMode();
                List<Integer> orderTypeList = new ArrayList<>();
                List<Integer> payModeList = new ArrayList<>();
                Map<String, Object> paymentJournalMap = new HashMap<>();
                paymentJournalMap.put("appId", paymentJournalVoOut.getAppId());
                paymentJournalMap.put("orgCode", paymentJournalVoOut.getHospitalCode());
                paymentJournalMap.put("startTime", paymentJournalVoOut.getStartTime());
                paymentJournalMap.put("endTime", paymentJournalVoOut.getEndTime());

                switch (orderModer) {//订单类型
                    case 0://所有
                        orderTypeList.add(1);
                        orderTypeList.add(2);
                        orderTypeList.add(3);
                        orderTypeList.add(4);
                        break;
                    case 1://挂号
                        orderTypeList.add(1);
                        orderTypeList.add(2);
                        break;
                    case 2://门诊
                        orderTypeList.add(3);
                        break;
                    case 3://住院
                        orderTypeList.add(4);
                        break;
                }
                paymentJournalMap.put("orderMode", orderTypeList);
                switch (tradeModer) {//支付类型
                    case 0://所有
                        payModeList.add(1);
                        payModeList.add(11);
                        payModeList.add(12);
                        payModeList.add(13);
                        payModeList.add(14);

                        payModeList.add(2);
                        payModeList.add(21);
                        payModeList.add(22);
                        payModeList.add(23);
                        payModeList.add(24);
                        payModeList.add(25);
                        payModeList.add(27);
                        break;
                    case 2://支付宝服务窗
                        payModeList.add(2);
                        payModeList.add(21);
                        payModeList.add(22);
                        payModeList.add(23);
                        payModeList.add(24);
                        payModeList.add(25);
                        payModeList.add(27);
                        break;
                    case 3://微信服务号
                        payModeList.add(1);
                        payModeList.add(11);
                        payModeList.add(12);
                        payModeList.add(13);
                        payModeList.add(14);
                        break;
                }
                paymentJournalMap.put("tradeMode", payModeList);
                logger.info("PayServiceImpl.PaymentJournalQuery.paymentJournalMap request-> {}", JsonUtils.toJsonString(paymentJournalMap));
                List<PaymentJournalResponseOut> paymentJournalList = paymentJournalServiceImpl.paymentJournalQuery(paymentJournalMap);
                logger.info("PayServiceImpl.PaymentJournalQuery.paymentJournalList response-> {}", JsonUtils.toJsonString(paymentJournalList));
                if (!CollectionUtils.isEmpty(paymentJournalList)) {
                    resCommon.setResult(paymentJournalList);
                } else {
                    logger.info("无订单数据:" + QueryJouralResponse.Common.NO_DATA.getMessage());
                    resCommon.setResultCodeAndMessage(QueryJouralResponse.Common.NO_DATA.getCode(),
                            QueryJouralResponse.Common.NO_DATA.getMessage());
                }
            }
        } catch (ValidateException e) {
            logger.error("参数为空:" + e.getMessage());
            resCommon.setResultCodeAndMessage(
                    QueryJouralResponse.Common.PARAMETRE_ERR.getCode(), e.getMessage());
        } catch (Exception e) {
            logger.error("数据查询异常[PayServiceImpl.PaymentJournalQuery]", e);
            resCommon.setResultCodeAndMessage(
                    QueryJouralResponse.Common.FAILURE.getCode(),
                    QueryJouralResponse.Common.FAILURE.getMessage()
            );
        }
        return resCommon;
    }
}
